#include "../include/scNet/Client.hpp"

#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdexcept>
#include <system_error>

namespace scNet {
	// 构造 初始化错误处理函数为默认抛出异常
	Client::Client() {
		error_handler_ = [](const std::string& err) { throw std::runtime_error(err); };
	}
	Client::~Client() {
		stop();
	} 

	// 继承ClientCore 的接口实现
	// 连接到指定服务器
	void Client::connect(const std::string& ip, uint16_t port) {
		if (connected_) return;  // 如果已经连接，直接返回
		try {
			// TCP 连接  使用 创建 SocketWrapper 对象
			socket_ = std::make_unique<SocketWrapper>(AF_INET, SOCK_STREAM);
			// 超时
			socket_->setTimeout(timeout_ms_);

			sockaddr_in server_addr{};  // 创建服务器地址结构
        	server_addr.sin_family = AF_INET;  // 设置地址族为 IPv4
        	server_addr.sin_port = htons(port);  // 设置端口号

			// !!!!!
			// IP 地址 转换成 网络字节序的二进制
			if (inet_pton(AF_INET, ip.c_str(), &server_addr.sin_addr) <= 0) {
				throw std::system_error(errno, std::generic_category(), "Invalid address");
			}

			// 尝试与服务器建立连接
			socket_->connect(reinterpret_cast<sockaddr*>(&server_addr), sizeof(server_addr));

			// 标志转换
			connected_ = true;
		} catch (std::exception& e) {
			error_handler_(std::string("Connection failed: ") + e.what());
			throw;
		}
	}  

	// 发送数据
    void Client::send(const std::string& data) {
		// 没连接就掉error_handle
		if (!connected_) {
			error_handler_("Not connected to server");
			return;
		}
		// 发送try来抓异常
		try {
			size_t total_sent = 0;	// 已经发送的字节数
			// 发到发完为止
			while (total_sent < data.size()) {
				ssize_t sent = socket_->send(data.data() + total_sent, data.size() - total_sent);
				if (sent <= 0)	throw std::system_error(errno, std::generic_category(), "Send failed");
				// 更新已经发送的
				total_sent += sent;
			}
		} catch (std::exception& e) {
			connected_ = false;		// 出现错误就转成未连接
			error_handler_(std::string("Send failed: ") + e.what());
			throw;
		}
	}  

	// 接收数据
    std::string Client::receive() {
		// 没连接就掉error_handle
		if (!connected_) {
			error_handler_("Not connected to server");
			return "";	// 注意返回类型
		}
		try {
			// 接收缓冲区
			char buf[4096];
			ssize_t received = socket_->recv(buf, sizeof(buf));
			// 接收异常 记得断开防止错误
			if (received <= 0) {
				connected_ = false;
				throw std::system_error(errno, std::generic_category(), "Receive failed");
			}
			return std::string(buf, received);
		} catch (const std::exception& e) {
			connected_ = false;  // 发生错误，设置为未连接
        	error_handler_(std::string("Receive failed: ") + e.what());  // 调用错误处理函数
        	throw;
		}
	}  

	// // 客户端不需要监听端口，空实现
    // void Client::start(uint16_t port = 0) {
		
	// }  

	// 停止客户端，断开连接
    void Client::stop() {
		connected_ = false;
		if (socket_) {
			socket_.reset();
		}
	}  

	// 错误处理函数
	void Client::setErrorHandler(std::function<void(const std::string&)> handler) {
		error_handler_ = handler;
	}

	// 设置超时
	void Client::setTimeout(int timeout_ms) {
		// ms 单位
		timeout_ms_  = timeout_ms;// 做一下更新
		if (socket_)	// 更新套接字超时时间
			socket_->setTimeout(timeout_ms_);
	}

	// 检查是否连接
	bool Client::isConnected() const {
		return connected_;
	}
}